<?php


namespace App\Http\Common;

use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use App\Http\Controllers\Controller;
use App\Models\Notice;
use App\Models\Role;
use App\Models\Semester;
use App\Models\SetSemester;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use OSS\OssClient;
use OSS\Core\OssException;

class BaseController extends Controller
{
    const SUCCESS = 200;            //成功
    const ADMIN_NOT_LOGGED_IN = 4000;//管理员未登录
    const NO_PERMISSION = 4001;     //无权限
    const NOT_LOGGED_IN = 4002;     //用户未登录
    const NOT_ASSIGN_LAN = 4003;    //不是指定局域网
    const ERROR = 4004;             //系统错误
    const FIELD_ERROR = 4005;       //字段错误
    const DATA_NOTFOUND = 4006;     //数据未找到
    const LIKED = 4007;             //已点赞

    //token前缀
    public $tokenPrefix = 'wdad.';

    /**
     * 返回JSON数据格式
     * @param $code
     * @param string $msg
     * @param array $data
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function returnJson($code, $msg = '', $data = [])
    {
        $result = [
            'msg' => $msg,
            'code' => $code,
            'data' => $data
        ];
        return response($result);
    }

    /**
     * 发送短信
     * @param $phone
     * @param $code
     * @throws ClientException
     */
    public function send($phone, $code)
    {
        AlibabaCloud::accessKeyClient(env('SMS_ACCESSKEY'), env('SMS_ACCESSKEYSECRET'))
            ->regionId('cn-shenzhen')
            ->asDefaultClient();

        try {
            AlibabaCloud::rpc()
                ->product('Dysmsapi')
                ->version('2017-05-25')
                ->action('SendSms')
                ->method('POST')
                ->host('dysmsapi.aliyuncs.com')
                ->options([
                    'query' => [
                        'PhoneNumbers' => $phone,
                        'SignName' => env('SIGNNAME'),
                        'TemplateCode' => env('TEMPLATECODE'),
                        'TemplateParam' => "{\"code\":\"$code\"}",
                    ],
                ])
                ->request();
        } catch (ClientException $e) {
            echo $e->getErrorMessage() . PHP_EOL;
        } catch (ServerException $e) {
            echo $e->getErrorMessage() . PHP_EOL;
        }
    }

    /**
     * 生成token
     * @param $id
     * @param $type
     * @return string
     */
    public function makeToken($id)
    {
        return md5(md5(time()) . $id);
    }

    /**
     * 获取当前周数
     * @return false|float
     */
    public function getNewWeeks(){
    $semester_id = $this->getNewSemester();
    $time =time();
    $long = Semester::where('id','=',$semester_id)->pluck('start_time') [0];
    if ($long>$time) return 1;
    $day = 7 - date('N',$long);
    $newday = date('N',$time);
    $newWeek = floor((($time - $long) / 86400 - $day - $newday ) / 7 + 2);
    return $newWeek;
    }

    /**
     * 获取当前学期id
     * @return mixed
     */
    public  function getNewSemester(){
        return SetSemester::first()['semester_id'];
    }
    /**
     * 获取用户权限id
     * @param $userId
     * @return mixed
     */
    public function getUserRole($userId){
        $userData = User::find($userId);
        return $userData->belongsToRole[0]->id;
    }

    /**
     * 获取所有路由
     * @param $user_id
     * @return mixed
     * @throws \Exception
     */
    public function getRouteAll($user_id){
        //获取用户权限
        $userData = User::find($user_id);
        $roleId = $userData->belongsToRole[0]->id;

        //获取用户所有路由
        $roleData = Role::find($roleId);
        $routeAll = $roleData->belongsToRoute;

        $newRouteAll = [];
        foreach ($routeAll as $key => $value){
            $newRouteAll[$key]['id'] = $value->id;
            $newRouteAll[$key]['route_name'] = $value->route_name;
            $newRouteAll[$key]['route_url'] = $value->route_url;
            $newRouteAll[$key]['route_method'] = $value->route_method;
            $newRouteAll[$key]['status'] = $value->status;
        }
        return $newRouteAll;
    }

    /**
     * 转换时间戳
     * @param $time
     * @return false|string
     */
    public function switchTime($time)
    {   if (empty($time)) $time = 0;
        return date('Y/m/d', $time);
    }

    public function switchPreciseTime($time)
    {   if (empty($time)) $time = 0;
        return date('Y/m/d H:s', $time);
    }

    //生成通知key
    public function  mkNoticeKey($user_id){
        return  'notice.' . md5( 'notice'. $user_id);
    }

    //添加通知内容
    public function  mkNoticeContent($admin_id,$user_id,$content ,$type = 1 ){
        $admin =  User::where('id','=',$admin_id)->pluck('username')[0];
        switch ($type){
            case 1:
                $user =  User::where('id','=',$user_id)->pluck('username');
                if (count($user) == 0){
                    return '已被炒鱿鱼的用户' ."\t\t被\t" . $admin ."\t\t". $content;
                }
                return  $user[0] ."\t\t被\t" . $admin ."\t\t". $content;
            case 2:
                return  $admin ."\t\t添加了\t". $content;
            case 3:
                return  $admin ."\t\t删除了 \t". $content;
                case 4:
                return  $admin ."\t\t修改了 \t". $content;
        }

    }

    // 添加未读通知
    public function  creatNoticeRedis($notice_id,$user_id){
        return  Redis::SADD($this->mkNoticeKey($user_id),$notice_id);
    }

    // 更改状态 以读
    public function  delNoticeRedis($notice_id,$user_id){
        return Redis::srem($this->mkNoticeKey($user_id),$notice_id);
    }
    // 更改状态 以读
    public function  delAllNoticeRedis($user_id){
        $notice_id = Redis::SMEMBERS($this->mkNoticeKey($user_id));
        foreach ($notice_id as $value){
            if(!Redis::srem($this->mkNoticeKey($user_id),$value)) return false;
        }
        return true;
    }

    //判断通知状态
    public function  inNoticeRedis($notice_id,$user_id){
        return Redis::sismember($this->mkNoticeKey($user_id),$notice_id);
    }

    //get未读通知id
    public function  getNoticeRedis($user_id){
        return Redis::smembers($this->mkNoticeKey($user_id));
    }

    //添加通知
    public function creatNotice($function_key,$user_id,$content,$bool = false)
    {
        //创建启动事务
        DB::beginTransaction();
        try {
            $notice_id = Notice::insertGetId([
                "function_key" => $function_key,
                "relation_user_id" => $user_id,
                "content" => $content,
                "create_time" => time(),
            ]);

            if ($bool){
                $user = User::get(['id']);
                foreach ($user as $key){
                    $this->creatNoticeRedis($notice_id,$key['id']);
                }
            }else{
                $this->creatNoticeRedis($notice_id,$user_id);
            }


            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            return $this->returnJson(self::ERROR,'添加失败');
        }
    }

    /**
     * 时间转换
     * @param $time
     * @return string
     */
    public function timeTransform($time){
        $currentTime = time();
        $timeDifference = $currentTime - $time;
        if ($timeDifference < 0){
            return $time;
        }elseif ($timeDifference < 60){
            return $timeDifference . '秒前';
        }elseif ($timeDifference < 3600){
            return floor($timeDifference / 60) . '分钟前';
        }elseif ($timeDifference < 86400){
            return floor($timeDifference / 3600) . '小时前';
        }elseif ($timeDifference < 2592000){
            return floor($timeDifference / 86400) . '天前';
        }elseif ($timeDifference < 31536000){
            return floor($timeDifference / 2592000) . '月前';
        }else{
            return floor($timeDifference / 31536000) . '年前';
        }
    }

    /**
     * 上传文件
     * @param $dir
     * @param $filename
     * @param $filePath
     * @return bool|null
     */
    public function uploadOss($dir, $filename, $filePath){
        try{
            $ossClient = new OssClient(env('SMS_ACCESSKEY'), env('SMS_ACCESSKEYSECRET'), env('ENDPOINT'));
            $object = $dir . '/' . $filename;
            $filename = $ossClient->uploadFile(env('BUCKET'), $object, $filePath);
        } catch(OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return false;
        }
        return $filename;
    }

    /**
     * 删除文件
     * @param $object
     * @return bool
     */
    public function deleteOss($object){
        try{
            $ossClient = new OssClient(env('SMS_ACCESSKEY'), env('SMS_ACCESSKEYSECRET'), env('ENDPOINT'));
            $ossClient->deleteObject(env('BUCKET'), $object);
        } catch(OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return false;
        }
        return true;
    }

    /**
     * 判断OSS中的文件是否存在
     * @param $object
     * @return bool
     */
    public function isFileExist($object){
        try{
            $ossClient = new OssClient(env('SMS_ACCESSKEY'), env('SMS_ACCESSKEYSECRET'), env('ENDPOINT'));

            $exist = $ossClient->doesObjectExist(env('BUCKET'), $object);
        } catch(OssException $e) {
            return false;
        }
        return $exist;
    }
}
